﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XFABManager;

namespace XFGameFramework
{

    internal class ViewManager
    {
        internal static void AddView(Module module, View view )
        { 
            if (!module.views.ContainsKey(view.AssetName))
                module.views.Add(view.AssetName, new Dictionary<int, View>());

            if (!module.views[view.AssetName].ContainsKey(view.Id))
            {
                view.Module = module;
                module.views[view.AssetName].Add(view.Id, view);
            }
            else
                Debug.LogWarningFormat("view name:{0} id:{1} 已经存在,请勿重复添加!", view.AssetName, view.Id);
        }

        internal static void RemoveView(Module module, View view)
        {
            if (module == null || view == null || string.IsNullOrEmpty(view.AssetName) ) return; 
            if (!module.views.ContainsKey(view.AssetName)) return;
            if (module.views[view.AssetName] == null) return; 
            // 只是单纯的移除 
            if (!module.views[view.AssetName].ContainsKey(view.Id)) return;

            view.Module = null;
            module.views[view.AssetName].Remove(view.Id); 
            EventManager.TriggerEvent(XFGameFrameworkEvents.ON_REMOVE_VIEW, view);
        }

        internal static GameObject LoadGameObject(Module module, string asset_name, Transform parent = null)
        {
            string project_name = module.ProjectName;
            GameObject obj = GameObjectLoader.Load(project_name, asset_name, parent);
            if (obj != null)
            {
                obj.transform.localPosition = Vector3.zero;
                return obj;
            }
            else {
                // 尝试从基础模块中加载
                foreach (var item in ModuleManager.baseModules)
                {
                    project_name = module.ProjectName;
                    obj = GameObjectLoader.Load(project_name, asset_name, parent);
                    if (obj != null)
                    {
                        obj.transform.localPosition = Vector3.zero;
                        return obj;
                    }
                }
            }

            return null;
        }

        // 加载
        internal static View LoadView(Module module , string asset_name, Transform parent = null, params object[] param)
        {  
            GameObject obj = LoadGameObject(module, asset_name, parent);

            if (obj == null) 
                return null;
            

            View view = obj.GetComponent<View>();

            if (view == null) {
                GameObjectLoader.UnLoad(obj);
                throw new Exception(string.Format("view:{0}加载失败,未查询到View组件!",asset_name));
            }

            view.AssetName = asset_name;
            
            AddView(module, view);
            view.OnLoaded(param);
            return view;
        }

        // 异步加载
        internal static LoadViewRequest<T> LoadViewAsync<T>(Module module, string asset_name, Transform parent = null, params object[] param) where T : View
        { 
            LoadViewRequest<T> loadView = new LoadViewRequest<T>();
            CoroutineStarter.Start(loadView.LoadView(module ,asset_name, parent, param));
            return loadView;
        }

        /// <summary>
        /// 清空某一个模块的所有View
        /// </summary>
        /// <param name="module"></param>
        internal static void ClearView(Module module)
        {

            List<View> tmp_views = new List<View>(module.views.Count);

            // 调用 关闭方法
            foreach (var item in module.views.Values)
                foreach (var view in item.Values)
                    tmp_views.Add(view);

            for (int i = 0; i < tmp_views.Count; i++)
                tmp_views[i].Close();

            tmp_views.Clear();
        }

        internal static void ClearView(Module module, string asset_name) 
        {
            if (module == null || !module.views.ContainsKey(asset_name) ) return;

            List<int> keys = new List<int>(module.views[asset_name].Count);

            foreach (var item in module.views[asset_name].Keys)
            {
                keys.Add(item);
            }

            foreach (var item in keys)
            {
                module.views[asset_name][item].Close();
            }

            module.views[asset_name].Clear();
        }

        internal static View GetView(Module module,string assetName,int id) 
        { 
            if(module.views.ContainsKey(assetName) && module.views[assetName].ContainsKey(id))
                return module.views[assetName][id];

            // 当前模块没有尝试去基础模块中查找
            foreach (var m in ModuleManager.baseModules.Values) {
                if (module == m) continue;
                if (m.views.ContainsKey(assetName) && m.views[assetName].ContainsKey(id)) 
                    return m.views[assetName][id];
            }

            return null;
        }

        internal static T GetView<T>(Module module,string assetName, int id) where T : View
        { 
            return GetView(module,assetName,id) as T;
        }


        internal static List<View> GetViews(Module module,string assetName) 
        {
            List<View> views = new List<View>();

            if (module.views.ContainsKey(assetName)) {
                foreach (var item in module.views[assetName].Values)
                    views.Add(item);
                
            }

            // 基础模块中查找
            foreach (var m in ModuleManager.baseModules.Values)
            {
                if (m == module) continue;
                if (!m.views.ContainsKey(assetName)) continue;
                foreach (var item in m.views[assetName].Values)
                    views.Add(item);
            }
             
            return views;
        }

        internal static List<T> GetViews<T>(Module module,string assetName) where T : View
        {
            List<T> views = new List<T>();

            if (module.views.ContainsKey(assetName))
            {
                foreach (var item in module.views[assetName].Values) {
                    T t = item as T;
                    if(t != null) views.Add(t);
                }

            }

            // 基础模块中查找
            foreach (var m in ModuleManager.baseModules.Values)
            {
                if (m == module) continue;
                if (!m.views.ContainsKey(assetName)) continue;
                foreach (var item in m.views[assetName].Values) {
                    T t = item as T;
                    if (t != null) views.Add(t);
                } 
            }

            return views;  
        }

    }
}